import factoryProtocol.Packet;
import factoryProtocol.Parser;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public abstract class UDPServer extends Thread {
    private Thread thread;
    private int PORT;
    private DatagramSocket socket = null;
    private boolean threadRunFlag = true;
    private Parser parser = new Parser();

    UDPServer(int port) {
        PORT = port;
    }

    protected abstract void onDataReceive(Packet data);
    public void run() {
        while (threadRunFlag) {
            // 创建数据包，用于接收客户端发送的数据
            byte[] data = new byte[1024];// 创建字节数组，指定接收的数据包的大小
            DatagramPacket datagramPacket = new DatagramPacket(data, data.length);
            // 接收客户端发送的数据
            try {
                socket.receive(datagramPacket);// 此方法在接收到数据报之前会一直阻塞
                // 从数据包里取出读取数据
                byte[] buf = datagramPacket.getData();

                Packet packet = null;
                // 依次解析数据
                for (int i=0;i<datagramPacket.getLength();i++)
                {
                   System.out.print(String.format("%x ",buf[i]));
                    packet = parser.message_parse_char(buf[i]);
                    if(packet != null){
                        System.out.println("解析成功");
                        onDataReceive(packet);
                    }
                }
                System.out.print(String.format("\r\n"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public void start() {
        // 创建服务器端DatagramSocket，指定端口
        try {
            socket = new DatagramSocket(PORT);
        } catch (SocketException e) {
            e.printStackTrace();
        }


        if (thread == null) {
            thread = new Thread(this);
            thread.start();
        }
    }

    public void sendData(InetAddress ip, int port, byte[] data) {
        DatagramPacket packet = new DatagramPacket(data, data.length, ip, port);
        try {
            socket.send(packet);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public void mstop() {
        socket.close();
        threadRunFlag = false;
    }
}
